package com.info.zhiduoduo.weixin.service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.info.zhiduoduo.common.configs.CommonConfig;
import com.info.zhiduoduo.common.configs.PayConfig;
import com.info.zhiduoduo.common.configs.ZddUrlConfig;
import com.info.zhiduoduo.common.constants.Constants;
import com.info.zhiduoduo.common.constants.SmartResult;
import com.info.zhiduoduo.common.constants.StatusMsg;
import com.info.zhiduoduo.common.constants.system.UserType;
import com.info.zhiduoduo.common.constants.company.CompanyPayType;
import com.info.zhiduoduo.common.constants.project.ProjectType;
import com.info.zhiduoduo.common.formbean.BaseSimpleFormBean;
import com.info.zhiduoduo.common.utils.DateUtil;
import com.info.zhiduoduo.common.utils.EasyExcelUtil;
import com.info.zhiduoduo.common.utils.RandomUtil;
import com.info.zhiduoduo.core.service.common.BaseService;
import com.info.zhiduoduo.repository.dto.invoice.CountByDate;
import com.info.zhiduoduo.repository.dto.invoice.InvoiceBriefDto;
import com.info.zhiduoduo.repository.dto.invoice.InvoiceDetailDto;
import com.info.zhiduoduo.repository.dto.project.ProjectDto;
import com.info.zhiduoduo.repository.entity.company.Company;
import com.info.zhiduoduo.repository.entity.invoice.Invoice;
import com.info.zhiduoduo.repository.entity.maker.Maker;
import com.info.zhiduoduo.repository.entity.maker.MakerAccount;
import com.info.zhiduoduo.repository.entity.maker.MakerStudio;
import com.info.zhiduoduo.repository.mapper.company.CompanyProjectMapper;
import com.info.zhiduoduo.repository.mapper.invoice.InvoiceMapper;
import com.info.zhiduoduo.repository.mapper.maker.MakerAccountMapper;
import com.info.zhiduoduo.weixin.dto.project.ProjectInvoiceCountDto;
import com.info.zhiduoduo.weixin.formbean.invoice.InvoiceFormBean;
import com.info.zhiduoduo.weixin.formbean.invoice.OfflinePayReceiptFormBean;
import com.info.zhiduoduo.weixin.formbean.invoice.QueryInvoiceFormBean;
import com.info.zhiduoduo.weixin.formbean.taxer.WXPayFromBean;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

@Transactional
@Service
public class InvoiceService extends BaseService {

	@Resource
	InvoiceMapper invoiceMapper;
	@Resource
	MakerAccountMapper makerAccountMapper;
	@Resource
	CompanyProjectMapper projectMapper;

	@Autowired
	CommonConfig commonConfig;
	@Autowired
	ZddUrlConfig zddUrlConfig;
	@Autowired
	PayConfig payConfig;

	public SmartResult saveInvoice(BaseSimpleFormBean<InvoiceFormBean> baseSimpleFormBean) {
		SmartResult smartResult = new SmartResult();

		InvoiceFormBean invoiceFormBean = baseSimpleFormBean.getReqdata();

		if (null == invoiceFormBean) {
			smartResult.setStateMsg(StatusMsg.StatusMsg_101);
			return smartResult;
		}

		int userid = baseSimpleFormBean.getUserid();

		//创客是否存在
		MakerStudio user = new MakerStudio().selectById(userid);
		if (null == user) {
			smartResult.setStateMsg(StatusMsg.StatusMsg_201);
			return smartResult;
		}

		//账户是否实名
		MakerAccount makerAccount = makerAccountMapper.getUserAccountByUserId(userid);
		if (null == makerAccount) {
			smartResult.setStateMsg(StatusMsg.StatusMsg_201);
			return smartResult;
		}
		if (Constants.realname_auth_4 > makerAccount.getRealnameAuth()) {
			smartResult.setStateMsg(StatusMsg.StatusMsg_202);
			return smartResult;
		}

		int projectid = invoiceFormBean.getProjectid();
		Invoice invoice = projectMapper.getPendingInvoiceDetail(projectid);
		if (null == invoice) {
			smartResult.setStateMsg(StatusMsg.StatusMsg_301);
			return smartResult;
		}

		BeanUtils.copyProperties(invoiceFormBean, invoice);
		invoice.setState(Constants.invoicestate_2);
		invoice.updateById();

		return smartResult;
	}

	public SmartResult<InvoiceBriefDto> queryInvoiceForUser(BaseSimpleFormBean<QueryInvoiceFormBean> formBean) {

		int userid = formBean.getUserid();
		QueryInvoiceFormBean reqdata = formBean.getReqdata();

		String name = reqdata.getName();
		int invoicetype = reqdata.getInvoicetype();
		int state = reqdata.getState();

		List<InvoiceBriefDto> list;
		Page<InvoiceBriefDto> page = PageHelper.startPage(formBean.getPage(), formBean.getRows());
		//开票中,或已开票
		list = invoiceMapper.getBriefListByUserid(userid, name, invoicetype, state);

		return smartResultPage(page);
	}

	public SmartResult<InvoiceBriefDto> queryInvoiceForCompany(BaseSimpleFormBean<QueryInvoiceFormBean> formBean) {
		int compid = formBean.getUserid();
		QueryInvoiceFormBean reqdata = formBean.getReqdata();

		String name = reqdata.getName();
		int invoicetype = reqdata.getInvoicetype();
		int state = reqdata.getState();

		List<InvoiceBriefDto> list;
		Page<InvoiceBriefDto> page = PageHelper.startPage(formBean.getPage(), formBean.getRows());
		//开票中,或已开票
		list = invoiceMapper.getBriefListByCompid(1, compid, name, invoicetype, state);

		return smartResultPage(page);
	}

	public SmartResult saveOfflinePayReceipt(BaseSimpleFormBean<OfflinePayReceiptFormBean> formBean) {
		@Valid OfflinePayReceiptFormBean reqdata = formBean.getReqdata();
		String receipt = reqdata.getPayReceipt();
		int invoiceid = reqdata.getId();

		new Invoice().setId(invoiceid).setPayReceipt(receipt).updateById();

		return smartResult();
	}

	public SmartResult<InvoiceDetailDto> getDetail(BaseSimpleFormBean<Integer> formBean) {
		@Valid Integer invoiceid = formBean.getReqdata();
		InvoiceDetailDto invoinceDetail = invoiceMapper.getInvoinceDetail(invoiceid);
		return smartResult(invoinceDetail);
	}

	public SmartResult payInvoiceServiceCharge(BaseSimpleFormBean<Integer> formBean) {

		int idtype = formBean.getIdtype();
		Invoice invoice = new Invoice().selectById(formBean.getReqdata());
		if (invoice == null) return errorParamSmartResult();
		if (invoice.getPayId() != CompanyPayType.OFFLINE_DIRECT) return smartResult(StatusMsg.StatusMsg_325);

		String openid = "";
		if (idtype == UserType.MAKER) {
			Maker maker = new Maker().selectById(invoice.getUserid());
			if (maker == null) return smartResult(StatusMsg.StatusMsg_201);

			openid = maker.getOpenid();
		} else if (idtype == UserType.COMPANY) {
			Company company = new Company().selectById(invoice.getCompid());
			if (company == null) return smartResult(StatusMsg.StatusMsg_302);

			openid = company.getOpenid();
		}

		//支付以分为单位
		int orderPrice = invoice.getPayAmount().multiply(BigDecimal.valueOf(100)).intValue();
		// int orderPrice = 1;
		WXPayFromBean wxPayFromBean = new WXPayFromBean().setOpenid(openid)
				.setOrderNo(invoice.getApplyno())
				.setOrderPrice(orderPrice)
				.setOrderDesc("线下项目开票:" + invoice.getContent())
				.setOrderType(3);
		RestTemplate rest = new RestTemplate();
		return rest.postForObject(zddUrlConfig.getBasePayUrl() + payConfig.getWxpayUrl(), wxPayFromBean, SmartResult.class);
	}

	public void downloadInvoice(HttpServletResponse response) {

		List<CountByDate> invoiceCount = invoiceMapper.countByDate();
		List<CountByDate> projectCount = projectMapper.countByDate();
		LocalDate start = LocalDate.of(2020, 1, 1);
		;
		List<ProjectInvoiceCountDto> list = Stream.iterate(start, d -> d.plusDays(1))
				.limit(DateUtil.getIntervalDays(start, LocalDate.now()) + 1)
				.map(date -> {
					Date curr = DateUtil.localDate2Date(date);
					ProjectInvoiceCountDto dto = new ProjectInvoiceCountDto().setDate(curr);
					invoiceCount.stream().filter(c -> c.getDate().equals(curr)).findAny().ifPresent(c -> dto.setInvoiceCount(c.getCount()));
					projectCount.stream().filter(c -> c.getDate().equals(curr)).findAny().ifPresent(c -> dto.setProjectCount(c.getCount()));

					return dto;
				})
				.collect(Collectors.toList());

		EasyExcelUtil.download(response, "开票项目数", ProjectInvoiceCountDto.class, list);
	}
}
